#ifndef __RCC_H
#define __RCC_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "system_remap.h"

typedef struct
{
  uint32_t SYSCLK_Frequency;  /*!< returns SYSCLK clock frequency expressed in Hz */
  uint32_t HCLK_Frequency;    /*!< returns HCLK clock frequency expressed in Hz */
  uint32_t PCLK1_Frequency;   /*!< returns PCLK1 clock frequency expressed in Hz */
}RCC_ClocksTypeDef;

/**
  * @}
  */

/** @defgroup RCC_Exported_Constants
  * @{
  */

/** @defgroup RTC_configuration 
  * @{
  */


#define RCC_RTCEN       								 ((uint32_t)0x00000008)        /*!< RTC clock enable */
/**
  * @}
  */ 

/** @defgroup PLL_entry_clock_source 
  * @{
  */

#define RCC_PLLSource_HSI_Div2           ((uint32_t)0x00000000)
#define RCC_PLLSource_HSE_Div1           ((uint32_t)0x00010000)
#define RCC_PLLSource_HSE_Div2           ((uint32_t)0x00030000)


/**
  * @}
  */ 

/** @defgroup PLL_multiplication_factor 
  * @{
  */

#define RCC_PLLMul_2                    ((uint32_t)0x00000000)
#define RCC_PLLMul_3                    ((uint32_t)0x00002000)
#define RCC_PLLMul_4                    ((uint32_t)0x00004000)
#define RCC_PLLMul_5                    ((uint32_t)0x00006000)
#define RCC_PLLMul_6                    ((uint32_t)0x00008000)
#define RCC_PLLMul_7                    ((uint32_t)0x0000A000)
#define RCC_PLLMul_8                    ((uint32_t)0x0000C000)
#define RCC_PLLMul_9                    ((uint32_t)0x0000E000)
#define RCC_PLLMul_10                   ((uint32_t)0x00012000)
#define RCC_PLLMul_11                   ((uint32_t)0x00014000)
#define RCC_PLLMul_12                   ((uint32_t)0x00018000)
#define RCC_PLLMul_13                   ((uint32_t)0x0001A000)
#define RCC_PLLMul_14                   ((uint32_t)0x0001C000)
#define RCC_PLLMul_15                   ((uint32_t)0x0001E000)
#define RCC_PLLMul_16                   ((uint32_t)0x0001F000)


/** @defgroup System_clock_source 
  * @{
  */

#define RCC_SYSCLKSource_HSI             ((uint32_t)0x00000000)
#define RCC_SYSCLKSource_LSI             ((uint32_t)0x00000004)
#define RCC_SYSCLKSource_PLLCLK          ((uint32_t)0x00000008)

/**
  * @}
  */

/** @defgroup AHB_clock_source 
  * @{
  */

#define RCC_SYSCLK_Div1                  ((uint32_t)0x00000000)
#define RCC_SYSCLK_Div2                  ((uint32_t)0x00000080)
#define RCC_SYSCLK_Div4                  ((uint32_t)0x00000090)
#define RCC_SYSCLK_Div8                  ((uint32_t)0x000000A0)
#define RCC_SYSCLK_Div16                 ((uint32_t)0x000000B0)
#define RCC_SYSCLK_Div64                 ((uint32_t)0x000000C0)
#define RCC_SYSCLK_Div128                ((uint32_t)0x000000D0)
#define RCC_SYSCLK_Div256                ((uint32_t)0x000000E0)
#define RCC_SYSCLK_Div512                ((uint32_t)0x000000F0)

/**
  * @}
  */ 

/** @defgroup APB1_APB2_clock_source 
  * @{
  */

#define RCC_HCLK_Div1                    ((uint32_t)0x00000000)
#define RCC_HCLK_Div2                    ((uint32_t)0x00000400)
#define RCC_HCLK_Div4                    ((uint32_t)0x00000500)
#define RCC_HCLK_Div8                    ((uint32_t)0x00000600)
#define RCC_HCLK_Div16                   ((uint32_t)0x00000700)

/**
  * @}
  */


/** @defgroup ADC_clock_source 
  * @{
  */

#define RCC_PCLK2_Div2                   ((uint32_t)0x00000000)
#define RCC_PCLK2_Div4                   ((uint32_t)0x00004000)
#define RCC_PCLK2_Div6                   ((uint32_t)0x00008000)
#define RCC_PCLK2_Div8                   ((uint32_t)0x0000C000)

/**
  * @}
  */

/** @defgroup LSE_configuration 
  * @{
  */

#define RCC_LSE_OFF                      ((uint8_t)0x00)
#define RCC_LSE_ON                       ((uint8_t)0x01)

/**
  * @}
  */

/** @defgroup RTC_clock_source 
  * @{
  */

#define RCC_RTCCLKSource_LSE             ((uint32_t)0x00000010)
#define RCC_RTCCLKSource_LSI             ((uint32_t)0x00000000)																			
#define RCC_TKCLKSource_HSI_1V4         ((uint32_t)0x00000000)
#define RCC_TKCLKSource_LSI             ((uint32_t)0x00000100)																			
																			
/**
  * @}
  */

/** @defgroup AHB_peripheral 
  * @{
  */


#define RCC_AHBPeriph_SRAM               ((uint32_t)0x00000004)
#define RCC_AHBPeriph_FLITF              ((uint32_t)0x00000010)
#define RCC_AHBPeriph_CRC                ((uint32_t)0x00000040)

/**
  * @}
  */ 

/** @defgroup APB1_peripheral 
  * @{
  */

/**********************************************************************/

#define RCC_APB1Periph_WWDG              ((uint32_t)0x00000001)
#define RCC_APB1Periph_TIM6              ((uint32_t)0x00000020)
#define RCC_APB1Periph_ADC               ((uint32_t)0x00000040)
#define RCC_APB1Periph_TIM1              ((uint32_t)0x00000100)
#define RCC_APB1Periph_UART0             ((uint32_t)0x00000200)											
#define RCC_APB1Periph_I2C               ((uint32_t)0x00000400)
#define RCC_APB1Periph_SPI1              ((uint32_t)0x00000800)
#define RCC_APB1Periph_DMA1              ((uint32_t)0x00001000)
#define RCC_APB1Periph_UART2             ((uint32_t)0x00002000)
#define RCC_APB1Periph_PWMLED	           ((uint32_t)0x00004000)
#define RCC_APB1Periph_TK	               ((uint32_t)0x00008000)
#define RCC_APB1Periph_MIC        	     ((uint32_t)0x00008000)
#define RCC_APB1Periph_UART1             ((uint32_t)0x00010000)
#define RCC_APB1Periph_TIM14             ((uint32_t)0x00020000)
#define RCC_APB1Periph_TIM7              ((uint32_t)0x00040000)	
#define RCC_APB1Periph_SPI2              ((uint32_t)0x00080000)
#define RCC_APB1Periph_DMA2              ((uint32_t)0x00100000)
#define RCC_APB1Periph_SRAM              ((uint32_t)0x00200000)
#define RCC_APB1Periph_FLASH             ((uint32_t)0x00400000)
#define RCC_APB1Periph_SPI3              ((uint32_t)0x00800000)

/*********************************************************************************************/


/**
  * @}
  */

/** @defgroup Clock_source_to_output_on_MCO_pin 
  * @{
  */

#define RCC_MCO_NoClock                  ((uint32_t)0x00000000)
#define RCC_MCO_LSI                   	 ((uint32_t)0x00040000)
#define RCC_MCO_LSE                   	 ((uint32_t)0x00060000)
#define RCC_MCO_SYSCLK                   ((uint32_t)0x00080000)
#define RCC_MCO_HSI                      ((uint32_t)0x000A0000)
#define RCC_MCO_PLLCLK_Div2              ((uint32_t)0x000E0000)


/**
  * @}
  */

/** @defgroup RCC_Flag 
  * @{
  */




#define RCC_FLAG_LSIRDY                  ((uint32_t)0x00100000)
#define RCC_FLAG_LSERDY                  ((uint32_t)0x00200000)
#define RCC_FLAG_HSIRDY                  ((uint32_t)0x00400000)
#define RCC_FLAG_PLLRDY                  ((uint32_t)0x00800000)
																										 
#define RCC_FLAG_PINRST                  ((uint32_t)0x04000000)
#define RCC_FLAG_PORRST                  ((uint32_t)0x08000000)
#define RCC_FLAG_SFTRST                  ((uint32_t)0x10000000)
#define RCC_FLAG_IWDGRST                 ((uint32_t)0x20000000)
#define RCC_FLAG_WWDGRST                 ((uint32_t)0x40000000)
#define RCC_FLAG_LPWRRST                 ((uint32_t)0x80000000)


/**
  * @}
  */

/**
  * @}
  */

/** @defgroup RCC_Exported_Macros
  * @{
  */

/**
  * @}
  */

/** @defgroup RCC_Exported_Functions
  * @{
  */

void RCC_DeInit(void);
ErrorStatus RCC_WaitForLSIStartUp(void);
ErrorStatus RCC_WaitForLSEStartUp(void);
ErrorStatus RCC_WaitForHSIStartUp(void);
ErrorStatus RCC_WaitForPLLStartUp(void);
void RCC_HSICmd(FunctionalState NewState);
void RCC_PLLConfig(uint32_t RCC_PLLMul);
void RCC_PLLCmd(FunctionalState NewState);
void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
uint8_t RCC_GetSYSCLKSource(void);
void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
void RCC_PCLK1Config(uint32_t RCC_HCLK);
void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState);
void RCC_LSECmd(FunctionalState NewState);
void RCC_LSICmd(FunctionalState NewState);
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
void RCC_RTCCLKCmd(FunctionalState NewState);
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_MCOConfig(uint32_t RCC_MCO);
FlagStatus RCC_GetFlagStatus(uint32_t RCC_FLAG);
void RCC_ClearFlag(void);
void RCC_DBPCmd(FunctionalState NewState);

#ifdef __cplusplus
}
#endif

#endif /* __RCC_H */
